Option Explicit

' 将形如 yyyyMMdd hhmmss 的字符串转换成时间戳（Date）
' 
' 如果无法正常转换，将会返回 Empty
' @param s 需要转换的字符串
' @return Date
Public Function strToTimestamp(ByRef s As String) As Variant
    ' 1. 从字符串中抽取所有的数字
    Dim temp As String
    temp = UtilsString.extractNum(s)

    ' 2. 如果数字长度不是 yyyyMMddhhmmss ，则无法生成时间戳，返回 Empty
    If Len(temp) <> 14 Then
        strToTimestamp = Empty
        Exit Function
    End If

    ' 3. 生成时间戳
    Dim result As Date
    result = Mid(temp, 1, 4) & "-" & Mid(temp, 5, 2) & "-" & Mid(temp, 7, 2) & _ 
            " " & _
            Mid(temp, 9, 2) & ":" & Mid(temp, 11, 2) & ":" & Mid(temp, 13, 2)
    strToTimestamp = result
End Function

' 将形如 hhmmss 的字符串转换成时间（Date）
' 
' 如果无法正常转换，将会返回 Empty
' @param s 需要转换的字符串
' @return Date
Public Function strToTime(ByRef s As String) As Variant
    ' 1. 从字符串中抽取所有的数字
    Dim temp As String
    temp = UtilsString.extractNum(s)

    ' 2. 如果数字长度不是 hhmmss，则无法生成时间戳，返回 Empty
    If Len(temp) <> 6 Then
        strToTime = Empty
        Exit Function
    End If

    ' 3. 生成时间戳
    Dim result As Date
    result = TimeSerial(Mid(s, 1, 2), Mid(s, 3, 2), Mid(s, 5, 2))
            
    strToTime = result
End Function

' 将形如 yyyyMMdd 的字符串转换成时间（Date）
' 
' 如果无法正常转换，将会返回 Empty
' @param s 需要转换的字符串
' @return Date
Public Function strToDate(ByRef s As String) As Variant
    ' 1. 从字符串中抽取所有的数字
    Dim temp As String
    temp = UtilsString.extractNum(s)

    ' 2. 如果数字长度不是 yyyyMMdd，则无法生成时间戳，返回 Empty
    If Len(temp) <> 8 Then
        strToDate = Empty
        Exit Function
    End If

    ' 3. 生成时间戳
    Dim result As Date
    result = DateSerial(Mid(s, 1, 4), Mid(s, 5, 2), Mid(s, 7, 2))
            
    strToDate = result
End Function

' 对:字符串类型的 yyyyMMdd 型字符串 做日期加法，并返回结果字符串
'
' @param d 字符串类型的 yyyyMMdd 型字符串
' @param c 用于计算的数值
' @optional-param addType 计算类型
'                请参考: https://learn.microsoft.com/zh-cn/office/vba/Language/Reference/user-interface-help/dateadd-function
Public Function yyyyMMddStrAdd(ByRef d As String, ByRef c As Integer, Optional ByRef addType As String = "d") As String
    ' 防止值拷贝，这里不单独调用 yyyyMMdStrToDate，手动计算
    Dim temp As Date
    temp = DateSerial(Mid(d, 1, 4), Mid(d, 5, 2), Mid(d, 7, 2))
    yyyyMMddStrAdd = Format(DateAdd(addType, c, temp), "yyyyMMdd")
End Function

' 将:字符串类型的 yyyyMMdd 型字符串 转换成日期
'
' @param d 字符串类型的 yyyyMMdd 型字符串
Public Function yyyyMMdStrToDate(ByRef d As String) As Date
    yyyyMMdStrToDate = DateSerial(Mid(d, 1, 4), Mid(d, 5, 2), Mid(d, 7, 2))
End Function

' 获取毫秒级的时间戳字符串
'
' @return 毫秒级的时间戳字符串
Public Function getTimestampForMillisecond() As String
    ' 1. 获取毫秒数
    Dim ms As Double
    ms = Timer * 1000 Mod 1000

    ' 2. 生成时间戳
    getTimestampForMillisecond = Format(Now, "yyyymmddhhnnss") & Format(ms, "000")
End Function